package com.zndroid.base.ui.atomic;

import android.app.Activity;

import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.Stack;

/**
 * @author lzy
 * Activity manager
 */
@SuppressWarnings("unused")
public final class ActivityManager {
    public void addActivity(Activity activity) {
        if (stacks == null) {
            stacks = new Stack<>();
        }
        stacks.add(new WeakReference<>(activity));
    }

    public void removeActivity(Activity activity) {
        if (stacks != null) {
            stacks.remove(new WeakReference<>(activity));
        }
    }

    public void clearActivities() {
        if (stacks != null) {
            stacks.clear();
            stacks = null;
        }
    }

    /**
     * 检查弱引用是否释放，若释放，则从栈中清理掉该元素
     */
    public void checkWeakReference() {
        if (stacks != null) {
            for (Iterator<WeakReference<Activity>> it = stacks.iterator(); it.hasNext(); ) {
                WeakReference<Activity> activityReference = it.next();
                Activity temp = activityReference.get();
                if (temp == null) {
                    it.remove();// 使用迭代器来进行安全的加锁操作
                }
            }
        }
    }

    /**
     * 获取当前Activity
     * @return 当前（栈顶）activity
     */
    public Activity currentActivity() {
        checkWeakReference();
        if (stacks != null && !stacks.isEmpty()) {
            return stacks.lastElement().get();
        }
        return null;
    }

    /**
     * 结束当前Activity
     */
    public void finishActivity() {
        Activity activity = currentActivity();
        if (activity != null) {
            finishActivity(activity);
        }
    }

    /**
     * 结束指定类名的所有Activity
     * @param cls 指定的类的class
     */
    public void finishActivity(Class<?> cls) {
        if (stacks != null) {
            for (Iterator<WeakReference<Activity>> it = stacks.iterator(); it.hasNext(); ) {
                WeakReference<Activity> activityReference = it.next();
                Activity activity = activityReference.get();
                if (activity == null) {
                    // 清理掉已经释放的activity
                    it.remove();
                    continue;
                }
                if (activity.getClass().equals(cls)) {
                    it.remove();
                    activity.finish();
                }
            }
        }
    }

    /**
     * 结束所有Activity
     */
    public void finishAllActivity() {
        if (stacks != null) {
            for (Iterator<WeakReference<Activity>> it = stacks.iterator(); it.hasNext(); ) {
                WeakReference<Activity> activityReference = it.next();
                Activity activity = activityReference.get();
                if (activity != null) {
                    activity.finish();
                }
            }
            stacks.clear();
        }
    }

    /**
     * 结束指定的Activity
     * @param activity 指定的activity实例
     */
    public void finishActivity(Activity activity) {
        if (activity != null) {
            for (Iterator<WeakReference<Activity>> it = stacks.iterator(); it.hasNext(); ) {
                WeakReference<Activity> activityReference = it.next();
                Activity temp = activityReference.get();
                if (temp == null) {
                    // 清理掉已经释放的activity
                    it.remove();
                    continue;
                }
                if (temp == activity) {
                    it.remove();
                }
            }
            activity.finish();
        }
    }

    /**
     * 退出应用程序
     */
    public void exitApp() {
        try {
            finishAllActivity();
            // 从操作系统中结束掉当前程序的进程
            android.os.Process.killProcess(android.os.Process.myPid());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Stack<WeakReference<Activity>> stacks;

    private ActivityManager(){
        stacks = new Stack<>();
    }
    private static class Inner {
        volatile static ActivityManager AM = new ActivityManager();
    }

    public static ActivityManager getManager() {
        return Inner.AM;
    }
}
